package org.jeecg.modules.workflow.service.change.imp;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.boc.ewr.bcimp.entity.Pro;
import com.boc.ewr.bcimp.service.IProService;
import com.boc.ewr.business.entity.ProtocolChangeApply;
import com.boc.ewr.business.mapper.ProtocolChangeApplyMapper;
import com.boc.ewr.util.SysRoleEnum;
import com.boc.ewr.util.file.enumeration.ProcessStatusEnum;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.mybatis.query.LambdaQueryWrapperX;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.workflow.vo.change.protocol.BpmChgProtocolCreateReqVo;
import org.jeecg.common.workflow.vo.change.protocol.BpmChgProtocolPageReqVo;
import org.jeecg.common.workflow.vo.change.protocol.BpmChgProtocolRespVo;
import org.jeecg.common.workflow.vo.change.protocol.BpmChgProtocolUpdateReqVo;
import org.jeecg.modules.workflow.convert.change.BpmChgProtocolConvert;
import org.jeecg.modules.workflow.enums.task.BpmProcessInstanceResultEnum;
import org.jeecg.modules.workflow.service.change.BpmChgProtocolService;
import org.jeecg.modules.workflow.service.task.BpmProcessInstanceService;
import org.jeecg.modules.workflow.service.task.BpmTaskService;
import org.jeecg.modules.workflow.service.task.dto.BpmProcessInstanceCreateReqDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;

import static java.util.Calendar.JANUARY;
import static org.jeecg.common.exception.util.ServiceExceptionUtil.exception;
import static org.jeecg.modules.workflow.enums.ErrorCodeConstants.CHG_PROTOCOL_NOT_EXISTS;

/**
 * @author : Wzz
 * @create : 2023-04- 27- 10:09
 * @desc :变更申请-协议变更申请 Service 实现类
 */
@Service
@Validated
public class BpmChgProtocolServiceImpl implements BpmChgProtocolService {

    /**
     * 协议变更申请 对应的流程定义 KEY
     */
    public static final String PROCESS_KEY = "protocol_change";

    /**
     * 网关流转条件参数名
     */
    public static final String ROLE = "role";

    @Resource
    private ProtocolChangeApplyMapper mapper;

    @Resource
    private BpmProcessInstanceService processInstanceApi;

    @Autowired
    BpmChgProtocolConvert convert;

    @Autowired
    private BpmTaskService bpmTaskService;

    @Autowired
    private ISysBaseAPI sysBaseAPI;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createChgProtocol(String userId, BpmChgProtocolCreateReqVo createReqVO) {
        // 插入 签约机构变更申请单
        ProtocolChangeApply protocolChangeApply = this.convert.convert(createReqVO);

        protocolChangeApply.setUserId(userId);
        protocolChangeApply.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
        protocolChangeApply.setApplyDate(new Date());

        protocolChangeApply.setCheckSta(ProcessStatusEnum.NOEFFECTIVE.getIndex());
        protocolChangeApply.setOperatPsn(this.getLoginUser().getRealname());

        mapper.insert(protocolChangeApply);

        // 发起 BPM 流程
        Map<String, Object> processInstanceVariables = new HashMap<>();
        // 添加条件流转参数
        List<String> roleCodeByLoginUser = sysBaseAPI.getRoleCodeByLoginUser(this.getLoginUser());
        for (String roleStr : roleCodeByLoginUser) {
            if (SysRoleEnum.ORG_CA_HANDLER.getCode().equals(roleStr)) {
                processInstanceVariables.put(ROLE, SysRoleEnum.ORG_CA_HANDLER.getCode());
                break;
            } else if (SysRoleEnum.BRANCH_BUS_HANDLER.getCode().equals(roleStr)) {
                processInstanceVariables.put(ROLE, SysRoleEnum.BRANCH_BUS_HANDLER.getCode());
                break;
            } else if (SysRoleEnum.ADMIN_CA_HANDLER.getCode().equals(roleStr)) {
                processInstanceVariables.put(ROLE, SysRoleEnum.ADMIN_CA_HANDLER.getCode());
                break;
            }
        }

        BpmProcessInstanceCreateReqDTO bpmProcessInstanceCreateReqDTO = new BpmProcessInstanceCreateReqDTO();
        bpmProcessInstanceCreateReqDTO.setProcessDefinitionKey(PROCESS_KEY);
        bpmProcessInstanceCreateReqDTO.setVariables(processInstanceVariables);
        bpmProcessInstanceCreateReqDTO.setBusinessKey(String.valueOf(protocolChangeApply.getId()));
        String processInstanceId = processInstanceApi.createProcessInstance(userId, bpmProcessInstanceCreateReqDTO);

        // 更新 工作流的编号
        ProtocolChangeApply protocolChangeApplyUpdate = new ProtocolChangeApply();
        protocolChangeApplyUpdate.setId(protocolChangeApply.getId());
        protocolChangeApplyUpdate.setProcessInstanceId(processInstanceId);
        mapper.updateById(protocolChangeApplyUpdate);
        return protocolChangeApplyUpdate.getId();
    }

    @Override
    public void updateChgProtocolResult(String id, Integer result) {
        validateChgProtocolExists(id);
        ProtocolChangeApply protocolChangeApply = new ProtocolChangeApply();
        protocolChangeApply.setId(id);
        protocolChangeApply.setResult(result);

        if (result.equals(BpmProcessInstanceResultEnum.REJECT.getResult())) {
            protocolChangeApply.setApprovePsn(this.getLoginUser().getRealname());
            protocolChangeApply.setCheckSta(ProcessStatusEnum.REJECT.getIndex());
        }

        if (result.equals(BpmProcessInstanceResultEnum.APPROVE.getResult())) {
            protocolChangeApply.setApprovePsn(this.getLoginUser().getRealname());
            protocolChangeApply.setCheckSta(ProcessStatusEnum.EFFECTIVE.getIndex());
        }

        mapper.updateById(protocolChangeApply);
    }

    @Override
    public ProtocolChangeApply getChgProtocol(String id) {
        return mapper.selectById(id);
    }

    @Override
    public IPage<ProtocolChangeApply> getChgProtocolPage(String userId, BpmChgProtocolPageReqVo pageReqVO) {
        Page<ProtocolChangeApply> page = new Page<>(pageReqVO.getPageNum(), pageReqVO.getPageSize());
        LambdaQueryWrapperX<ProtocolChangeApply> wrapper = new LambdaQueryWrapperX<ProtocolChangeApply>()
                .eqIfPresent(ProtocolChangeApply::getUserId, userId)
                .orderByDesc(ProtocolChangeApply::getId);
        return mapper.selectPage(page, wrapper);
    }

    @Override
    public BpmChgProtocolRespVo getInfoByProtocolNo(String protocolNo) {
        BpmChgProtocolRespVo bpmChgProtocolRespVo = convert.getInfoByProtocolNo(protocolNo);
        return bpmChgProtocolRespVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateChgProtocol(String userId, BpmChgProtocolUpdateReqVo updateReqVO) {
        // 更新业务
        ProtocolChangeApply protocolChangeApply = this.convert.convert(updateReqVO);
        protocolChangeApply.setUserId(userId);
        protocolChangeApply.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
        protocolChangeApply.setApplyDate(new Date());

        mapper.updateById(protocolChangeApply);

        // 更新工作流
        bpmTaskService.updateBusinessFormFlow(userId, updateReqVO.getTaskId(), null);
    }

    private void validateChgProtocolExists(String id) {
        if (mapper.selectById(id) == null) {
            throw exception(CHG_PROTOCOL_NOT_EXISTS);
        }
    }

    private LoginUser getLoginUser() {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        return sysUser;
    }
}
